home *** CD-ROM | disk | FTP | other *** search
/ Aminet 13 / Aminet 13 - August 1996.iso / Aminet / mus / misc / ChordianV1_0.lha / Chordian.c < prev    next >
C/C++ Source or Header  |  1996-06-10  |  6KB  |  257 lines

  1.  
  2. /*********************************************************************************
  3.  **    Chordian -- a program to mix tunes of a sample into a chord        **
  4.  **                                         **
  5.  **     Released to the public domain by Andreas Fredriksson (dep@canit.se)    **
  6.  **                                        **
  7.  **    If you use this program or the source code in any way, mention my name.    **
  8.  **                                        **
  9.  *********************************************************************************/
  10.  
  11. #include <stdio.h>
  12. #include <math.h>
  13.  
  14. float diffs[]={ 1.0000, 1.0594, 1.1225, 1.1892,
  15.         1.2600, 1.3348, 1.4142, 1.4983,
  16.         1.5874, 1.6818, 1.7817, 1.8878 };
  17.  
  18. char infoline[]={"Chordian v1.0 -- copyright (c)1996 by Andreas Fredriksson (dep@canit.se)\n"};
  19.  
  20. char usage[]={"
  21. Usage:\n
  22. Chordian <sample> <output> [i] n1 n2 [n3..]\n
  23. <sample>    the sample you wish to make a chord from
  24. <output>    the chord sample to create
  25. i        use interpolation
  26. the n values are tones relative to the basenote
  27. values n1,n2 are required but up to 4 may be given\n
  28. example:
  29.     Chordian organ.raw organchord i 0 3 7\n
  30. This would create a minor chord from the sample 'organ.raw' and
  31. place the result in the file 'organchord'.\n\n"};
  32.  
  33.  
  34. long filesize(FILE *f)
  35.     {
  36.     long s;
  37.     fseek(f,0,2); s=ftell(f); rewind(f);
  38.     return(s);
  39.     }
  40.  
  41.  
  42. /*  cut(): not needed anymore but kept if I want to change the smp-size someday */
  43.  
  44. /*
  45. void cut(float *f,long s)
  46.     {
  47.     if(*f>=s) *f=s-1;
  48.     }
  49. */
  50.  
  51.  
  52.  
  53. /* macro to get the fractional part from a float */
  54.  
  55. #define frac(a) (a-floor(a))
  56.  
  57. int main(int argc, char *argv[])
  58.     {
  59.     FILE *in,*out;
  60.     int x;
  61.     long csize,size=0;
  62.     char interpolate=0, num, *sample, *chord;
  63.     char numnotes=-1, notes[4]={0,0,0,0}, *tmp;
  64.  
  65.     float pos1=0,pos2=0,pos3=0,pos4=0,tmpfloat,v1,v2,v3,v4;
  66.     float step1=0,step2=0,step3=0,step4=0;
  67.  
  68.     if(argc<5) { printf("%s%s",infoline,usage); exit(0); }
  69.  
  70.     printf("%s",infoline);
  71.  
  72.     /* open files needed */
  73.     if(!(in=fopen(argv[1],"rb"))) { printf("Couldn't open file '%s'.\n",argv[1]); exit(0); }
  74.     if(!(out=fopen(argv[2],"wb"))) { printf("Couldn't create file '%s'.\n",argv[2]); fclose(in); exit(0);}
  75.  
  76.     /* check for 'i' flag */
  77.     if(*argv[3]=='i' || *argv[3]=='I')
  78.         {
  79.         interpolate=1;
  80.         num=4;
  81.         puts("Interpolation enabled.");
  82.         }
  83.     else num=3;
  84.  
  85.     /* read the notes */
  86.     tmp=notes;    /* set up a pointer */
  87.     while(num<=argc && numnotes<4)
  88.         {
  89.         *tmp++=atoi(argv[num]);
  90.         numnotes++;
  91.         num++;
  92.         }
  93.  
  94.     /* print some info */
  95.     printf("Mixing sample '%s' to '%s'.\n",argv[1],argv[2]);
  96.     printf("Notes in use (%d) :",numnotes);
  97.  
  98.     for(x=0;x<numnotes;x++)
  99.         {
  100.         printf(" %d",notes[x]);
  101.         }
  102.     printf("\n");
  103.  
  104.  
  105.  
  106.     /* allocate memory and read the sample */
  107.  
  108.     size=filesize(in);
  109.  
  110.     sample=(char *)malloc(size);
  111.     chord=(char *)malloc(size);
  112.  
  113.     if( (!(sample)) || (!(chord)) )
  114.         {
  115.         fclose(in); fclose(out);
  116.         puts("Error: Out of memory.");
  117.         exit(0);
  118.         }
  119.  
  120.     fread(sample,1,size,in);
  121.  
  122.     /* do the mixing */
  123.  
  124.     step1=diffs[notes[0]];    /* get stepvalues */
  125.     step2=diffs[notes[1]];
  126.     step3=diffs[notes[2]];
  127.     step4=diffs[notes[3]];
  128.  
  129.     /* find biggest stepvalue, divide size with it to get chord size */
  130.  
  131.     tmpfloat=-10;
  132.     if(step1>tmpfloat) tmpfloat=step1;
  133.     if(step2>tmpfloat) tmpfloat=step2;
  134.     if(step3>tmpfloat) tmpfloat=step3;
  135.     if(step4>tmpfloat) tmpfloat=step4;
  136.  
  137.     csize=size/tmpfloat;
  138.  
  139.     printf("Sample size: %d\n",size);
  140.     printf(" Chord size: %d (based on highest note)\n",csize);
  141.  
  142.     tmp=chord;    /* set up a pointer */
  143.  
  144.     if(interpolate)
  145.         {
  146.         switch(numnotes)
  147.             {
  148.             case 2:
  149.                 for(x=0;x<size;x++)
  150.                     {
  151.                     v1=sample[(int)pos1]*(1-frac(pos1))+
  152.                       +sample[(int)pos1+1]*(frac(pos1));
  153.                     v2=sample[(int)pos2]*(1-frac(pos2))+
  154.                       +sample[(int)pos2+1]*(frac(pos2));
  155.                     *tmp++=(v1+v2)/2;
  156.                     pos1+=step1;
  157.                     pos2+=step2;
  158.                     }
  159.                 break;
  160.  
  161.             case 3:
  162.                 for(x=0;x<size;x++)
  163.                     {
  164.                     v1=sample[(int)pos1]*(1-frac(pos1))+
  165.                       +sample[(int)pos1+1]*(frac(pos1));
  166.                     v2=sample[(int)pos2]*(1-frac(pos2))+
  167.                       +sample[(int)pos2+1]*(frac(pos2));
  168.                     v3=sample[(int)pos3]*(1-frac(pos3))+
  169.                       +sample[(int)pos3+1]*(frac(pos3));
  170.                     *tmp++=(v1+v2+v3)/3;
  171.                     pos1+=step1;
  172.                     pos2+=step2;
  173.                     pos3+=step3;
  174.                     }
  175.                 break;
  176.  
  177.             case 4:
  178.                 for(x=0;x<size;x++)
  179.                     {
  180.                     v1=sample[(int)pos1]*(1-frac(pos1))+
  181.                       +sample[(int)pos1+1]*(frac(pos1));
  182.                     v2=sample[(int)pos2]*(1-frac(pos2))+
  183.                       +sample[(int)pos2+1]*(frac(pos2));
  184.                     v3=sample[(int)pos3]*(1-frac(pos3))+
  185.                       +sample[(int)pos3+1]*(frac(pos3));
  186.                     v4=sample[(int)pos4]*(1-frac(pos4))+
  187.                       +sample[(int)pos4+1]*(frac(pos4));
  188.                     *tmp++=(v1+v2+v3+v4)/4;
  189.                     pos1+=step1;
  190.                     pos2+=step2;
  191.                     pos3+=step3;
  192.                     pos4+=step4;
  193.                     }
  194.                 break;
  195.             }
  196.         }
  197.     else
  198.         {
  199.         switch(numnotes)
  200.             {
  201.             case 2:
  202.                 for(x=0;x<csize;x++)
  203.                     {
  204.                     /*cut(&pos1,size); cut(&pos2,size);*/
  205.                     *tmp++= (sample[(int)pos1]
  206.                         +sample[(int)pos2])/2;
  207.                     pos1+=step1;
  208.                     pos2+=step2;
  209.                     }
  210.                 break;
  211.  
  212.  
  213.             case 3:
  214.                 for(x=0;x<csize;x++)
  215.                     {
  216.                     /*cut(&pos1,size); cut(&pos2,size); cut(&pos3,size);*/
  217.                     *tmp++= (sample[(int)pos1]
  218.                         +sample[(int)pos2]
  219.                         +sample[(int)pos3])/3;
  220.                     pos1+=step1;
  221.                     pos2+=step2;
  222.                     pos3+=step3;
  223.                     }
  224.                 break;
  225.  
  226.  
  227.             case 4:
  228.                 for(x=0;x<csize;x++)
  229.                     {
  230.                     /*cut(&pos1,size); cut(&pos2,size); cut(&pos3,size); cut(&pos4,size);*/
  231.                     *tmp++= (sample[(int)pos1]
  232.                         +sample[(int)pos2]
  233.                         +sample[(int)pos3]
  234.                         +sample[(int)pos4])/4;
  235.                     pos1+=step1;
  236.                     pos2+=step2;
  237.                     pos3+=step3;
  238.                     pos4+=step4;
  239.                     }
  240.                 break;
  241.             }
  242.         }
  243.  
  244.     /* save data to disk */
  245.  
  246.     printf("Saving data.. ");
  247.     fwrite(chord,1,csize,out);
  248.     printf("done.\n");
  249.  
  250.     /* close files & free memory */
  251.  
  252.     free(sample);
  253.     free(chord);
  254.     fclose(in);
  255.     fclose(out);
  256.     }
  257.